//WhatATool, Assignment 1B from the Stanford Iphone dev course, CS193p
//Last Updated Friday 29th January by samuel.mcnamara
//Get the .pdf @ http://www.stanford.edu/class/cs193p/cgi-bin/drupal/system/files/assignments/Assignment1B_0.pdf

#import <Foundation/Foundation.h>

//Prototype Functions
void PrintPath();
void PrintProcess();
void UrlDictionary();
void ObjectInfo();
void doSomething();

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    
    //Each Subtask is a function
        PrintPath();
        NSLog(@"===");
        PrintProcess();
        NSLog(@"===");
        UrlDictionary();
		NSLog(@"===");
        ObjectInfo();
        
        [pool drain];
    return 0;
}

//Printpath, extrapolate path using tilde (~) and add each component into an array element
void PrintPath()
{
        //Expand tilde
        NSString *path = [@"~/Documents/xcode/WhatATool/" stringByExpandingTildeInPath];
        //pathComponents method returns an array
        NSArray *components = [path pathComponents];            
        //Instantiate enumerator with HANDY ENUMERATOR METHOD
        NSEnumerator *enumerate = [components objectEnumerator];        
        
        //id is an object of ambiguous class, NSLog outputs description property, which represents object as NSString
        id object;      
        while (object = [enumerate nextObject])
        {
                NSLog(@"%@", [object description]);
        }
        
}

//PrintProcess, use NSProcessInfo to display...uh...Process Information
void PrintProcess()
{
        NSString *processname = [[NSProcessInfo processInfo] processName];
        int pid = [[NSProcessInfo processInfo] processIdentifier];
        //Represents ProcessInfo properties as a C-type integer and a NSString
        NSLog(@"The Process Name is %@ and Process ID is %d", processname, pid);
}

//UrlDictionary, Create a mutable (changable) dictionary, add key/value pairs of String/URL
//Enumerate by key but only display objects whose key begins with 'iPhone'
void UrlDictionary()
{
        //Instantiate
        NSMutableDictionary *mutableDict = [[NSMutableDictionary alloc] init];
        NSMutableArray *phrase = [[NSMutableArray alloc] init];
        //Populate
        [mutableDict setObject:[NSURL URLWithString:@"http://sdciphone.ning.com"] forKey: @"iPhone dev on Ning"];
        [mutableDict setObject:[NSURL URLWithString:@"http://developer.apple.com/iphone"] forKey: @"iPhone resources on Apple"];
        [mutableDict setObject:[NSURL URLWithString:@"http://www.youporn.com"] forKey: @"pr0n"];
        //Discriminate    
        for (id key in mutableDict)
        {
                [phrase setArray:[[key description] componentsSeparatedByString:@" "]];
                
                if ([[[phrase objectAtIndex:0] description] isEqualToString: @"iPhone"])
                {
                        NSLog(@"Key: %@, URL: %@",[key description],[mutableDict objectForKey:key]);                                                                                    
                }
        }
        //Emancipate
        [phrase release];
        [mutableDict release];
        //LOLOLOLOLOLOLOLOL
}

//ObjectInfo, a bad example of object introspection. Create a mutable array of objects (can be of any type
//in ObjC), then display properties about each object
void ObjectInfo()
{
        //Clumsily instantiate and commit objects to the array
        NSMutableArray *objects = [[NSMutableArray alloc] init];
        
        NSString *string = [[NSString alloc] initWithString:@"So Ruff, So Tuff"];
        [objects addObject:string];
        NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:@"w00t",@"Opposite of Fail",nil];
        [objects addObject:dictionary];
        NSNumber *integer = [[NSNumber alloc] initWithInt: 482774];
        [objects addObject:integer];
        NSMutableString *mutableString = [[NSMutableString alloc] initWithString:@"it's the beat"];
        [objects addObject:mutableString];
        
        //Iterate through array and test for each condition, all whilst navigating around ObjC's total absence of
        //a boolean data type.
        for (id obj in objects)
        {
                NSLog(@"%@ is Member of Class NSString: %@", [obj class], [obj isMemberOfClass:[NSString class]]?@"YES":@"NO");
                NSLog(@"-> is Kind of Class NSString: %@", [obj isKindOfClass:[NSString class]]?@"YES":@"NO");
                if ([obj respondsToSelector:@selector(lowercaseString)]){
                        NSLog(@"-> responds to lowercaseString: YES");
                        NSLog(@"-> output from selector: %@", [obj performSelector:@selector(lowercaseString)]);
                }
                else
                        NSLog(@"-> responds to lowercaseString: NO");
                NSLog(@"---");
        }
        
        //Clean up rogue objects in memory, I can justify this more when I know how to.
        [string release];
        [dictionary release];
        [integer release];
        [mutableString release];
        [objects release];      
         
}

void doSomething()
{
	//PolygonShape *poly = [[PolygonShape alloc] init];
}
